package v1

import (
	"context"
	"net/http"
	"regexp"
)

// 参数匹配的正则表达式，用于提取路径中的参数
var paramRegex = regexp.MustCompile(`:([a-zA-Z0-9]+)`)

// route 表示一个路由项
type route struct {
	path    string         // 路由路径，如 "/user/:id"
	handler http.Handler   // 处理函数
	params  []string       // 路径中的参数名，如 ["id"]
	regex   *regexp.Regexp // 用于匹配路径的正则表达式
}

// Param 表示路径参数
type Param struct {
	Key   string
	Value string
}

// Params 表示一组路径参数
type Params []Param

// Get 用于获取参数值
func (p Params) Get(key string) string {
	for _, param := range p {
		if param.Key == key {
			return param.Value
		}
	}
	return ""
}

// contextKey 用于在context中存储参数
type contextKey struct{}

// paramContextKey 是用于在context中存储参数的键
var paramContextKey = contextKey{}

// ParamRouter 实现了Router接口的路由结构体
type ParamRouter struct {
	routes []*route // 存储所有路由
}

// NewParamRouter 创建一个新的路由实例
func NewParamRouter() *ParamRouter {
	return &ParamRouter{
		routes: []*route{},
	}
}

// 重复注册返回false
func (r *ParamRouter) HandleFunc(path string, handler http.HandlerFunc) bool {
	return r.Handle(path, handler)
}

// Handle 注册一个处理函数到指定路径
func (r *ParamRouter) Handle(path string, handler http.Handler) bool {
	// 提取路径中的参数
	params := paramRegex.FindAllStringSubmatch(path, -1)
	paramNames := make([]string, len(params))
	for i, param := range params {
		paramNames[i] = param[1]
	}

	// 将路径转换为正则表达式，用于匹配请求路径
	regexPath := paramRegex.ReplaceAllString(path, `([^/]+)`)
	regexPath = "^" + regexPath + "$"
	regex, err := regexp.Compile(regexPath)
	if err != nil {
		return false
	}

	// 添加路由
	r.routes = append(r.routes, &route{
		path:    path,
		handler: handler,
		params:  paramNames,
		regex:   regex,
	})

	return true
}

// Delete 从路由中删除指定路径的处理函数
func (r *ParamRouter) Delete(path string) {
	newRoutes := []*route{}
	for _, route := range r.routes {
		if route.path != path {
			newRoutes = append(newRoutes, route)
		}
	}
	r.routes = newRoutes
}

// Mount 暂不实现
func (r *ParamRouter) Mount(prefix string, subRouter Router) bool {
	return false
}

// Unmount 暂不实现
func (r *ParamRouter) Unmount(prefix string) bool {
	return false
}

// ServeHTTP 实现http.Handler接口
func (r *ParamRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	path := req.URL.Path

	// 查找匹配的路由
	for _, route := range r.routes {
		// 检查路径是否匹配
		if !route.regex.MatchString(path) {
			continue
		}

		// 提取参数值
		matches := route.regex.FindStringSubmatch(path)
		params := make(Params, len(route.params))
		for i, paramName := range route.params {
			if i+1 < len(matches) {
				params[i] = Param{Key: paramName, Value: matches[i+1]}
			}
		}

		// 将参数存储到context中
		ctx := req.Context()
		ctx = context.WithValue(ctx, paramContextKey, params)
		newReq := req.WithContext(ctx)

		// 调用处理函数
		route.handler.ServeHTTP(w, newReq)
		return
	}

	// 如果没有找到匹配的路由，返回404
	http.NotFound(w, req)
}

// GetParams 从请求中获取路径参数
func GetParams(req *http.Request) Params {
	if params, ok := req.Context().Value(paramContextKey).(Params); ok {
		return params
	}
	return nil
}
